
<!DOCTYPE html>
<html lang="en" class="loading">
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Database - weifan</title>
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <meta name="google" content="notranslate" />
    <meta name="keywords" content="TriDiamond Obsidian,"> 
    <meta name="description" content="Database notes


关系型数据库和非关系型数据库
关系数据库
非关系型数据库
对比


redis
redis持久化
RDB持久化
AOF持久化
优缺点




Mysql
主键
引擎,"> 
    <meta name="author" content="weifan"> 
    <link rel="alternative" href="atom.xml" title="weifan" type="application/atom+xml"> 
    <link rel="icon" href="/img/favicon.png"> 
    <link href="https://fonts.loli.net/css?family=Roboto+Mono|Rubik&display=swap" rel="stylesheet">
    
<link rel="stylesheet" href="//at.alicdn.com/t/font_1429596_nzgqgvnmkjb.css">

    
<link rel="stylesheet" href="//cdn.bootcss.com/animate.css/3.7.2/animate.min.css">

    
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/social-share.js/1.0.16/css/share.min.css">

    
<link rel="stylesheet" href="//cdn.bootcss.com/codemirror/5.48.4/codemirror.min.css">

    
<link rel="stylesheet" href="//cdn.bootcss.com/codemirror/5.48.4/theme/dracula.css">

    
<link rel="stylesheet" href="/css/obsidian.css">

    
<link rel="stylesheet" href="/css/ball-atom.min.css">

<meta name="generator" content="Hexo 4.2.1"></head>


<body class="loading">
    <div class="loader">
        <div class="la-ball-atom la-2x">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
    <span id="config-title" style="display:none">weifan</span>
    <div id="loader"></div>
    <div id="single">
    <div class="scrollbar gradient-bg-rev"></div>
<div id="top" style="display: block;">
    <div class="bar" style="width: 0;"></div>
    <div class="navigation animated fadeIn fast delay-1s">
        <img id="home-icon" class="icon-home" src="/img/favicon.png" alt="" data-url="https://wifidu.gitee.io">
        <div id="play-icon" title="Play/Pause" class="iconfont icon-play"></div>
        <h3 class="subtitle">Database</h3>
        <div class="social">
            <!--        <div class="like-icon">-->
            <!--            <a href="javascript:;" class="likeThis active"><span class="icon-like"></span><span class="count">76</span></a>-->
            <!--        </div>-->
            <div>
                <div class="share">
                    
                        <a href="javascript:;" class="iconfont icon-share1"></a>
                        <div class="share-component-cc" data-disabled="facebook,douban,linkedin,diandian,tencent,google"></div>
                    
                </div>
            </div>
        </div>
    </div>
</div>

    <div class="section">
        <div class=article-header-wrapper>
    <div class="article-header">
        <div class="article-cover animated fadeIn" style="
            animation-delay: 600ms;
            animation-duration: 1.2s;
            background-image: 
                radial-gradient(ellipse closest-side, rgba(0, 0, 0, 0.65), #100e17),
                url(/img/cover.jpg) ">
        </div>
        <div class="else">
            <p class="animated fadeInDown">
                
                <a href="/categories/Database"><b>「
                    </b>DATABASE<b> 」</b></a>
                
                June 07, 2020
            </p>
            <h3 class="post-title animated fadeInDown"><a href="/2020/06/07/Database/" title="Database" class="">Database</a>
            </h3>
            
            <p class="post-count animated fadeInDown">
                
                <span>
                    <b class="iconfont icon-text2"></b> <i>Words count</i>
                    12k
                </span>
                
                
                <span>
                    <b class="iconfont icon-timer__s"></b> <i>Reading time</i>
                    11 mins.
                </span>
                
                
                
                <span id="busuanzi_container_page_pv">
                    <b class="iconfont icon-read"></b> <i>Read count</i>
                    <span id="busuanzi_value_page_pv">0</span>
                </span>
                
            </p>
            
            
            <ul class="animated fadeInDown post-tags-list" itemprop="keywords"><li class="animated fadeInDown post-tags-list-item"><a class="animated fadeInDown post-tags-list-link" href="/tags/Database/" rel="tag">Database</a></li></ul>
            
        </div>
    </div>
</div>

<div class="screen-gradient-after">
    <div class="screen-gradient-content">
        <div class="screen-gradient-content-inside">
            <div class="bold-underline-links screen-gradient-sponsor">
                <p>
                    <span class="animated fadeIn delay-1s"></span>
                </p>
            </div>
        </div>
    </div>
</div>

<div class="article">
    <div class='main'>
        <div class="content markdown animated fadeIn">
            <h1 id="Database-notes"><a href="#Database-notes" class="headerlink" title="Database notes"></a>Database notes</h1><!-- vim-markdown-toc Redcarpet -->

<ul>
<li><a href="#关系型数据库和非关系型数据库">关系型数据库和非关系型数据库</a><ul>
<li><a href="#关系数据库">关系数据库</a></li>
<li><a href="#非关系型数据库">非关系型数据库</a></li>
<li><a href="#对比">对比</a></li>
</ul>
</li>
<li><a href="#redis">redis</a><ul>
<li><a href="#redis持久化">redis持久化</a><ul>
<li><a href="#rdb持久化">RDB持久化</a></li>
<li><a href="#aof持久化">AOF持久化</a></li>
<li><a href="#优缺点">优缺点</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#mysql">Mysql</a><ul>
<li><a href="#主键">主键</a></li>
<li><a href="#引擎">引擎</a></li>
<li><a href="#索引">索引</a><ul>
<li><a href="#分类">分类</a></li>
<li><a href="#索引原理">索引原理</a></li>
<li><a href="#聚集索引和非聚集索引">聚集索引和非聚集索引</a></li>
<li><a href="#正确使用索引">正确使用索引</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<!-- vim-markdown-toc -->

<h2 id="关系型数据库和非关系型数据库"><a href="#关系型数据库和非关系型数据库" class="headerlink" title="关系型数据库和非关系型数据库"></a><a href="https://www.jianshu.com/p/fd7b422d5f93" target="_blank" rel="noopener">关系型数据库和非关系型数据库</a></h2><h3 id="关系数据库"><a href="#关系数据库" class="headerlink" title="关系数据库"></a>关系数据库</h3><blockquote>
<p>由二维表及其之间的联系组成的一个数据组织。</p>
</blockquote>
<ul>
<li><strong>关系</strong>：一张二维表，每个关系都具有一个关系名，即<strong>表名</strong>。</li>
<li><strong>元祖</strong>：二维表中的一行，在数据库中被称为<strong>记录</strong>。</li>
<li><strong>属性</strong>：二维表中的一列，在数据库中被称为<strong>字段</strong>。</li>
<li><strong>域</strong>　：属性的取值范围，也就是数据库中某一列的取值限制。</li>
<li>关键字：一组可以唯一标识元组的属性，数据库中常称为主键，由一个或多个列组成</li>
<li>关系模式：指对关系的描述。其格式为：关系名(属性1，属性2， … … ，属性N)，在数据库中成为表结构</li>
</ul>
<p>数据库事务必须具备ACID特性:</p>
<ol>
<li>Atomic原子性</li>
<li>Consistency一致性</li>
<li>Isolation隔离性</li>
<li>Durability持久性</li>
</ol>
<h3 id="非关系型数据库"><a href="#非关系型数据库" class="headerlink" title="非关系型数据库"></a>非关系型数据库</h3><blockquote>
<p>没有关系的数据库。指非关系型的，分布式的，且一般不保证遵循ACID原则的数据存储系统。</p>
</blockquote>
<blockquote>
<p>非关系型数据库以键值对存储，且结构不固定，每一个元组可以有不一样的字段，每个元组可以根据需要增加一些自己的键值对，不局限于固定的结构，可以减少一些时间和空间的开销。</p>
</blockquote>
<h3 id="对比"><a href="#对比" class="headerlink" title="对比"></a>对比</h3><ol>
<li>成本：Nosql数据库简单易部署，基本都是开源软件，不需要像使用Oracle那样花费大量成本购买使用，相比关系型数据库价格便宜。</li>
<li>查询速度：Nosql数据库将数据存储于缓存之中，而且不需要经过SQL层的解析，关系型数据库将数据存储在硬盘中，自然查询速度远不及Nosql数据库。</li>
<li>存储数据的格式：Nosql的存储格式是key,value形式、文档形式、图片形式等等，所以可以存储基础类型以及对象或者是集合等各种格式，而数据库则只支持基础类型。</li>
<li>扩展性：关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。Nosql基于键值对，数据之间没有耦合性，所以非常容易水平扩展。</li>
<li>持久存储：Nosql不使用于持久存储，海量数据的持久存储，还是需要关系型数据库</li>
<li>数据一致性：非关系型数据库一般强调的是数据最终一致性，不像关系型数据库一样强调数据的强一致性，从非关系型数据库中读到的有可能还是处于一个中间态的数据，<br>Nosql不提供对事务的处理。</li>
</ol>
<h2 id="redis"><a href="#redis" class="headerlink" title="redis"></a>redis</h2><h3 id="redis持久化"><a href="#redis持久化" class="headerlink" title="redis持久化"></a><a href="https://www.cnblogs.com/wdliu/p/9377278.html" target="_blank" rel="noopener">redis持久化</a></h3><h4 id="RDB持久化"><a href="#RDB持久化" class="headerlink" title="RDB持久化"></a>RDB持久化</h4><blockquote>
<p>RDB持久化方式是通过快照(snapshotting)完成的，当符合一定条件时，redis会自动将内存中所有数据以二进制方式生成一份副本并存储在硬盘上。当redis重启时，并且AOF持久化未开启时，redis会读取RDB持久化生成的二进制文件(默认名称dump.rdb，可通过设置dbfilename修改)进行数据恢复，对于持久化信息可以用过命令“info Persistence”查看。</p>
</blockquote>
<p><strong>快照触发条件</strong></p>
<p>RDB生成快照可自动促发，也可以使用命令手动触发，以下是redis触发执行快照条件，后续会对每个条件详细说明：</p>
<ol>
<li>客户端执行命令save和bgsave会生成快照；</li>
<li>根据配置文件save m n规则进行自动快照；</li>
<li>主从复制时，从库全量复制同步主库数据，此时主库会执行bgsave命令进行快照；</li>
<li>客户端执行数据库清空命令FLUSHALL时候，触发快照；</li>
<li>客户端执行shutdown关闭redis时，触发快照；</li>
</ol>
<p><strong>RDB持久化配置</strong></p>
<pre><code>save m n
#配置快照(rdb)促发规则，格式：save &lt;seconds&gt; &lt;changes&gt;
#save 900 1  900秒内至少有1个key被改变则做一次快照
#save 300 10  300秒内至少有300个key被改变则做一次快照
#save 60 10000  60秒内至少有10000个key被改变则做一次快照
#关闭该规则使用svae “” 

dbfilename  dump.rdb
#rdb持久化存储数据库文件名，默认为dump.rdb

stop-write-on-bgsave-error yes 
#yes代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no表明忽略错误继续写文件。

rdbchecksum yes
#在写入文件和读取文件时是否开启rdb文件检查，检查是否有无损坏，如果在启动是检查发现损坏，则停止启动。

dir &quot;/etc/redis&quot;
#数据文件存放目录，rdb快照文件和aof文件都会存放至该目录，请确保有写权限

rdbcompression yes
#是否开启RDB文件压缩，该功能可以节约磁盘空间</code></pre><h4 id="AOF持久化"><a href="#AOF持久化" class="headerlink" title="AOF持久化"></a>AOF持久化</h4><blockquote>
<p>当redis存储非临时数据时，为了降低redis故障而引起的数据丢失，redis提供了AOF(Append Only File)持久化，从单词意思讲，将命令追加到文件。AOF可以将Redis执行的每一条写命令追加到磁盘文件(appendonly.aof)中,在redis启动时候优先选择从AOF文件恢复数据。由于每一次的写操作，redis都会记录到文件中，所以开启AOF持久化会对性能有一定的影响，但是大部分情况下这个影响是可以接受的，我们可以使用读写速率高的硬盘提高AOF性能。与RDB持久化相比，AOF持久化数据丢失更少，其消耗内存更少(RDB方式执行bgsve会有内存拷贝)。</p>
</blockquote>
<p><strong>开启AOF</strong></p>
<blockquote>
<p>默认情况下，redis是关闭了AOF持久化，开启AOF通过配置appendonly为yes开启，我们修改配置文件或者在命令行直接使用config set修改，在用config rewrite同步到配置文件。通过客户端修改好处是不用重启redis，AOF持久化直接生效。</p>
</blockquote>
<p><strong>重写触发条件</strong></p>
<p>AOF文件触发条件可分为手动触发和自动触发：</p>
<ul>
<li>手动触发：客户端执行bgrewriteaof命令。</li>
<li>自动触发：自动触发通过以下两个配置协作生效：<ul>
<li>auto-aof-rewrite-min-size: AOF文件最小重写大小，只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。</li>
<li>auto-aof-rewrite-percentage：当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比，如100代表当前AOF文件是上次重写的两倍时候才重写。　</li>
</ul>
</li>
</ul>
<blockquote>
<p>redis开启AOF之后会维护以上条件所需变量</p>
</blockquote>
<p><strong>AOF实现本质</strong></p>
<p>AOF实现本质是基于redis通讯协议，将命令以纯文本的方式写入到文件中。<br>redis协议：</p>
<p>首先Redis是以行来划分，每行以\r\n行结束。每一行都有一个消息头，消息头共分为5种分别如下:</p>
<p>(+) 表示一个正确的状态信息，具体信息是当前行+后面的字符。</p>
<p>(-)  表示一个错误信息，具体信息是当前行－后面的字符。</p>
<p>(<em>) 表示消息体总共有多少行，不包括当前行,</em>后面是具体的行数。</p>
<p>($) 表示下一行数据长度，不包括换行符长度\r\n,$后面则是对应的长度的数据。</p>
<p>(：) 表示返回一个数值，：后面是相应的数字节符。</p>
<p><strong>AOF配置参数</strong></p>
<pre><code>auto-aof-rewrite-min-size 64mb
#AOF文件最小重写大小，只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。

auto-aof-rewrite-percentage  100
#当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比，如100代表当前AOF文件是上次重写的两倍时候才重写。

appendfsync everysec
#no：不使用fsync方法同步，而是交给操作系统write函数去执行同步操作，在linux操作系统中大约每30秒刷一次缓冲。这种情况下，缓冲区数据同步不可控，并且在大量的写操作下，aof_buf缓冲区会堆积会越来越严重，一旦redis出现故障，数据
#always：表示每次有写操作都调用fsync方法强制内核将数据写入到aof文件。这种情况下由于每次写命令都写到了文件中, 虽然数据比较安全，但是因为每次写操作都会同步到AOF文件中，所以在性能上会有影响，同时由于频繁的IO操作，硬盘的使用寿命会降低。
#everysec：数据将使用调用操作系统write写入文件，并使用fsync每秒一次从内核刷新到磁盘。 这是折中的方案，兼顾性能和数据安全，所以redis默认推荐使用该配置。

aof-load-truncated yes
#当redis突然运行崩溃时，会出现aof文件被截断的情况，Redis可以在发生这种情况时退出并加载错误，以下选项控制此行为。
#如果aof-load-truncated设置为yes，则加载截断的AOF文件，Redis服务器启动发出日志以通知用户该事件。
#如果该选项设置为no，则服务将中止并显示错误并停止启动。当该选项设置为no时，用户需要在重启之前使用“redis-check-aof”实用程序修复AOF文件在进行启动。

appendonly no 
#yes开启AOF，no关闭AOF

appendfilename appendonly.aof
#指定AOF文件名，4.0无法通过config set 设置，只能通过修改配置文件设置。

dir /etc/redis
#RDB文件和AOF文件存放目录</code></pre><h4 id="优缺点"><a href="#优缺点" class="headerlink" title="优缺点"></a>优缺点</h4><p><strong>RDB</strong></p>
<p><strong>优点</strong>：</p>
<ul>
<li>RDB 是一个非常紧凑（compact）的文件，体积小，因此在传输速度上比较快，因此适合灾难恢复。</li>
<li>RDB 可以最大化 Redis 的性能：父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程，然后这个子进程就会处理接下来的所有保存工作，父进程无须执行任何磁盘 I/O 操作。</li>
<li>RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。</li>
</ul>
<p><strong>缺点</strong>：</p>
<ul>
<li>RDB是一个快照过程，无法完整的保存所以数据，尤其在数据量比较大时候，一旦出现故障丢失的数据将更多。</li>
<li>当redis中数据集比较大时候，RDB由于RDB方式需要对数据进行完成拷贝并生成快照文件，fork的子进程会耗CPU，并且数据越大，RDB快照生成会越耗时。</li>
<li>RDB文件是特定的格式，阅读性差，由于格式固定，可能存在不兼容情况。</li>
</ul>
<p><strong>AOF</strong></p>
<p><strong>优点</strong>：</p>
<ul>
<li>数据更完整，秒级数据丢失(取决于设置fsync策略)。</li>
<li>兼容性较高，由于是基于redis通讯协议而形成的命令追加方式，无论何种版本的redis都兼容，再者aof文件是明文的，可阅读性较好。</li>
</ul>
<p><strong>缺点</strong>：</p>
<ul>
<li>数据文件体积较大,即使有重写机制，但是在相同的数据集情况下，AOF文件通常比RDB文件大。</li>
<li>相对RDB方式，AOF速度慢于RDB，并且在数据量大时候，恢复速度AOF速度也是慢于RDB。</li>
<li>由于频繁地将命令同步到文件中，AOF持久化对性能的影响相对RDB较大，但是对于我们来说是可以接受的。</li>
</ul>
<h2 id="Mysql"><a href="#Mysql" class="headerlink" title="Mysql"></a>Mysql</h2><p><code>mysql_secure_installation</code></p>
<pre><code class="shell">pacman -S php-fpm libapache2-mod-php php-mysql</code></pre>
<h3 id="主键"><a href="#主键" class="headerlink" title="主键"></a>主键</h3><p>表通常具有包含唯一标识表中每一行的值的一列或一组列。这样的一列或多列称为表的主键 (PK)，用于强制表的实体完整性。在创建或修改表时，您可以通过定义 PRIMARY KEY 约束来创建主键。</p>
<blockquote>
<p>创建主键时，数据库引擎 会自动创建唯一的索引来强制实施 PRIMARY KEY 约束的唯一性要求。如果表中不存在聚集索引或未显式指定非聚集索引，则将创建唯一的聚集索引以强制实施 PRIMARY KEY 约束。</p>
</blockquote>
<h3 id="引擎"><a href="#引擎" class="headerlink" title="引擎"></a>引擎</h3><p>InnoDB 支持事务，支持行级别锁定，支持 B-tree、Full-text 等索引，不支持 Hash 索引；<br>MyISAM 不支持事务，支持表级别锁定，支持 B-tree、Full-text 等索引，不支持 Hash 索引；<br>Memory 不支持事务，支持表级别锁定，支持 B-tree、Hash 等索引，不支持 Full-text 索引；<br>NDB 支持事务，支持行级别锁定，支持 Hash 索引，不支持 B-tree、Full-text 等索引；<br>Archive 不支持事务，支持表级别锁定，不支持 B-tree、Hash、Full-text 等索引；</p>
<h3 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h3><h4 id="分类"><a href="#分类" class="headerlink" title="分类"></a>分类</h4><p>我们可以在创建上述索引的时候，为其指定索引类型，分两类:</p>
<ul>
<li>hash类型的索引：查询单条快，范围查询慢</li>
<li>btree类型的索引：b+树，层数越多，数据量指数级增长（我们就用它，因为innodb默认支持它）</li>
</ul>
<blockquote>
<p>表中除了聚集索引外其他索引都是辅助索引（Secondary Index，也称为非聚集索引）（unique key啊、index key啊），与聚集索引的区别是：辅助索引的叶子节点不包含行记录的全部数据。</p>
</blockquote>
<p>常用索引：</p>
<ul>
<li><p>普通索引INDEX：加速查找</p>
</li>
<li><p>唯一索引：</p>
<ul>
<li>主键索引PRIMARY KEY：加速查找+约束（不为空、不能重复）</li>
<li>唯一索引UNIQUE:加速查找+约束（不能重复）</li>
</ul>
</li>
<li><p>联合索引：</p>
<ul>
<li>PRIMARY KEY(id,name):联合主键索引</li>
<li>UNIQUE(id,name):联合唯一索引</li>
<li>INDEX(id,name):联合普通索引</li>
</ul>
</li>
</ul>
<h4 id="索引原理"><a href="#索引原理" class="headerlink" title="索引原理"></a>索引原理</h4><p><a href="https://www.cnblogs.com/fengqiang626/archive/2019/09/04/11459434.html#1%E4%BB%8B%E7%BB%8D" target="_blank" rel="noopener">Link</a></p>
<h4 id="聚集索引和非聚集索引"><a href="#聚集索引和非聚集索引" class="headerlink" title="聚集索引和非聚集索引"></a>聚集索引和非聚集索引</h4><blockquote>
<p>主键索引的叶子节点存的是整行数据。在 InnoDB 里，主键索引也被称为聚集索引（clustered index）。</p>
</blockquote>
<blockquote>
<p>非主键索引的叶子节点内容是主键的值。在 InnoDB 里，非主键索引也被称为二级索引（secondary index）。</p>
</blockquote>
<ol>
<li><p>mysql的innodb表，就是索引组织表，表中的所有数据行都放在索引上，这就约定了数据是严格按照顺序存放的，所以不管插入的先后顺序，它在那个物理上的那个位置与插入的先后顺序无关。</p>
</li>
<li><p>聚集索引，叶子节点存的是整行数据，直接通过这个聚集索引的键值找到某行</p>
</li>
<li><p>聚集索引，数据的物理存放顺序与索引顺序是一致的，即：只要索引是相邻的，那么对应的数据一定也是相邻地存放在磁盘上的。</p>
</li>
<li><p>聚集索引，数据行和相邻的键值紧凑地存储在一起，因为无法同时把数据行存放在两个不同的地方，所以一个表只能有一个聚集索引。</p>
</li>
<li><p>非聚集索引，叶子节点存的是字段的值，通过这个非聚集索引的键值找到对应的聚集索引字段的值，再通过聚集索引键值找到表的某行，类似oracle通过键值找到rowid，再通过rowid找到行</p>
</li>
<li><p>mysql的innodb表，其聚集索引相当于整张表，而整张表也是聚集索引。默认通过主键聚集数据，如果没有定义主键，则选择第一个非空的唯一索引，如果没有非空唯一索引，则选择rowid来作为聚集索引</p>
</li>
<li><p>mysql的innodb表，因为整张表也是聚集索引，select出来的结果是顺序排序的，比如主键字段的数据插入顺序可以是5、3、4、2、1,查询时不带order by得出的结果也是按1、2、3、4、5排序</p>
</li>
<li><p>通俗理解</p>
<ul>
<li><p>聚集索引：类似新华字典正文内容本身就是一种按照一定规则排列的目录</p>
</li>
<li><p>非聚集索引：这种目录纯粹是目录，正文纯粹是正文的排序方式</p>
</li>
<li><p>每个表只能有一个聚集索引，因为目录只能按照一种方法进行排序 。</p>
</li>
</ul>
</li>
<li><p>oracle一般使用堆表，mysql的innodb是索引组织表</p>
<ul>
<li><p>堆表以一种显然随机的方式管理，数据插入时时存储位置是随机的，主要是数据库内部块的空闲情况决定，数据会放在最合适的地方，而不是以某种特定顺序来放置。</p>
</li>
<li><p>堆表的存储速度因为不用考虑排序, 所以存储速度会比较快. 但是要查找符合某个条件的记录, 就必须得读取全部的记录以便筛选。</p>
</li>
<li><p>堆表其索引中记录了记录所在位置的rowid，查找的时候先找索引，然后再根据索引rowid找到块中的行数据。</p>
</li>
<li><p>堆表的索引和表数据是分离的</p>
</li>
<li><p>索引组织表，其行数据以索引形式存放，因此找到索引，就等于找到了行数据。</p>
</li>
<li><p>索引组织表索引和数据是在一起的</p>
</li>
</ul>
</li>
</ol>
<p>如果语句是 select * from T where ID=500，即 主键查询方式，则只需要搜索 ID 这棵 B+树 ；</p>
<p>如果语句是 select * from T where k=5，即 普通索引查询方式，则需要先搜索 k 索引树，得到 ID的值为 500，再到 ID 索引树搜索一次。这个过程称为回表</p>
<p>B+ 树为了维护索引有序性，在插入新值的时候需要做必要的维护。以上面为例，如果插入新的行 ID 值为 700，则只只需要在 R5 的记录后面插入一个新记录。如果新插入的 ID值为 400，就相对麻烦了，需要逻辑上挪动后面的数据，空出位置。</p>
<p>test1表 innodb引擎，索引和数据放在一个文件里面</p>
<p>-rw-r—– 1 mysql mysql  8678 Nov 20 14:05 test1.frm</p>
<p>-rw-r—– 1 mysql mysql 98304 Nov 20 16:51 test1.ibd</p>
<p>test2表 myisam引擎，索引和数据放在不同文件</p>
<p>-rw-r—– 1 mysql mysql  8558 Nov 22 10:22 test2.frm</p>
<p>-rw-r—– 1 mysql mysql     0 Nov 22 10:22 test2.MYD</p>
<p>-rw-r—– 1 mysql mysql  1024 Nov 22 10:22 test2.MYI</p>
<p><strong>InnoDB表的行被组织成称为聚集索引的索引结构 ，条目根据表的主键列进行排序。 数据访问针对对主键列进行筛选和排序的查询进行了优化，每个索引都包含每个条目的关联主键列的副本。 修改任何主键列的值是一项昂贵的操作。 因此，InnoDB表设计的一个重要方面是选择一个主键，该主键具有在最重要的查询中使用的列，并保持主键很短，很少更改值。</strong></p>
<blockquote>
<p>InnoDB术语表示主键索引。 InnoDB表存储基于主键列的值进行组织，以加速涉及主键列的查询和排序。 为获得最佳性能，请根据性能最关键的查询仔细选择主键列。 因为修改聚集索引的列是一项昂贵的操作，所以选择很少或从不更新的主列。在Oracle数据库产品中，此类表称为索引组织表。</p>
</blockquote>
<p>每个InnoDB表都有一个称为聚集索引的特殊索引，其中存储了行的数据。通常，聚集索引与主键同义。</p>
<p>在表上定义PRIMARY KEY时，InnoDB将其用作聚集索引 。为您创建的每个表定义主键。如果没有逻辑唯一且非空列或一组列，请添加一个新的自动增量列，其值将自动填充。</p>
<p>如果没有为表定义PRIMARY KEY，MySQL将找到第一个UNIQUE索引，其中所有键列都是NOT NULL，而InnoDB将它用作聚集索引。</p>
<p>如果表没有PRIMARY KEY或合适的UNIQUE索引，InnoDB会在包含行ID值的合成列内部生成名为GEN_CLUST_INDEX的隐藏聚集索引 。这些行按InnoDB分配给此类表中的行的ID排序。行ID是一个6字节的字段，在插入新行时会单调增加。因此，由行ID排序的行在物理上处于插入顺序。</p>
<p>通过聚集索引访问行很快，因为索引搜索直接指向包含所有行数据的页面。 如果表很大，则与使用与索引记录不同的页面存储行数据的存储组织相比，聚集索引体系结构通常会保存磁盘I / O操作。</p>
<p>除聚集索引之外的所有索引都称为辅助索引。 在InnoDB中，辅助索引中的每个记录都包含该行的主键列以及为辅助索引指定的列。 InnoDB使用此主键值来搜索聚集索引中的行。</p>
<h4 id="正确使用索引"><a href="#正确使用索引" class="headerlink" title="正确使用索引"></a><a href="https://www.cnblogs.com/fengqiang626/archive/2019/09/04/11459434.html#7%E6%AD%A3%E7%A1%AE%E4%BD%BF%E7%94%A8%E7%B4%A2%E5%BC%95" target="_blank" rel="noopener">正确使用索引</a></h4>
            <!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->
            <audio id="audio" loop="1" preload="auto" controls="controls"
                data-autoplay="false">
                <source type="audio/mpeg" src="">
            </audio>
            
            <ul id="audio-list" style="display:none">
                
                
                <li title='0' data-url='/statics/chengdu.mp3'></li>
                
                    
            </ul>
            
            
            
    <div id='gitalk-container' class="comment link"
        data-ae='true'
        data-ci='ec894e2b66f752e8b7fb'
        data-cs='3ccc2e92bb350688fe2c2dc2930189b62622bfb1'
        data-r='blog-comments'
        data-o='TriDiamond'
        data-a='TriDiamond'
        data-d=''
    >Comments</div>


            
            
        </div>
        <div class="sidebar">
            <div class="box animated fadeInRight">
                <div class="subbox">
                    <img src="/img/mei.jpeg" height=300 width=300></img>
                    <p>weifan</p>
                    <span>Think like an artist, develop like an artisan</span>
                    <dl>
                        <dd><a href="https://github.com/wifidu" target="_blank"><span
                                    class=" iconfont icon-github"></span></a></dd>
                        <dd><a href="" target="_blank"><span
                                    class=" iconfont icon-twitter"></span></a></dd>
                        <dd><a href="" target="_blank"><span
                                    class=" iconfont icon-stack-overflow"></span></a></dd>
                    </dl>
                </div>
                <ul>
                    <li><a href="/">7 <p>Articles</p></a></li>
                    <li><a href="/categories">6 <p>Categories</p></a></li>
                    <li><a href="/tags">6 <p>Tags</p></a></li>
                </ul>
            </div>
            
            
            
            <div class="box sticky animated fadeInRight faster">
                <div id="toc" class="subbox">
                    <h4>Contents</h4>
                    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Database-notes"><span class="toc-number">1.</span> <span class="toc-text">Database notes</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#关系型数据库和非关系型数据库"><span class="toc-number">1.1.</span> <span class="toc-text">关系型数据库和非关系型数据库</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#关系数据库"><span class="toc-number">1.1.1.</span> <span class="toc-text">关系数据库</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#非关系型数据库"><span class="toc-number">1.1.2.</span> <span class="toc-text">非关系型数据库</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#对比"><span class="toc-number">1.1.3.</span> <span class="toc-text">对比</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redis"><span class="toc-number">1.2.</span> <span class="toc-text">redis</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#redis持久化"><span class="toc-number">1.2.1.</span> <span class="toc-text">redis持久化</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Mysql"><span class="toc-number">1.3.</span> <span class="toc-text">Mysql</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#主键"><span class="toc-number">1.3.1.</span> <span class="toc-text">主键</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#引擎"><span class="toc-number">1.3.2.</span> <span class="toc-text">引擎</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#索引"><span class="toc-number">1.3.3.</span> <span class="toc-text">索引</span></a></li></ol></li></ol></li></ol>
                </div>
            </div>
            
            
        </div>
    </div>
</div>

    </div>
</div>
    <div id="back-to-top" class="animated fadeIn faster">
        <div class="flow"></div>
        <span class="percentage animated fadeIn faster">0%</span>
        <span class="iconfont icon-top02 animated fadeIn faster"></span>
    </div>
</body>
<footer>
    <p class="copyright" id="copyright">
        &copy; 2020
        <span class="gradient-text">
            weifan
        </span>.
        Powered by <a href="http://hexo.io/" title="Hexo" target="_blank" rel="noopener">Hexo</a>
        Theme
        <span class="gradient-text">
            <a href="https://github.com/TriDiamond/hexo-theme-obsidian" title="Obsidian" target="_blank" rel="noopener">Obsidian</a>
        </span>
        <small><a href="https://github.com/TriDiamond/hexo-theme-obsidian/blob/master/CHANGELOG.md" title="v1.4.3" target="_blank" rel="noopener">v1.4.3</a></small>
    </p>
</footer>

<script type="text/javascript" src="https://cdn.bootcss.com/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script>
  MathJax.Hub.Config({
    "HTML-CSS": {
      preferredFont: "TeX",
      availableFonts: ["STIX", "TeX"],
      linebreaks: {
        automatic: true
      },
      EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50)
    },
    tex2jax: {
      inlineMath: [
        ["$", "$"],
        ["\\(", "\\)"]
      ],
      processEscapes: true,
      ignoreClass: "tex2jax_ignore|dno",
      skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    },
    TeX: {
      noUndefined: {
        attributes: {
          mathcolor: "red",
          mathbackground: "#FFEEEE",
          mathsize: "90%"
        }
      },
      Macros: {
        href: "{}"
      }
    },
    messageStyle: "none"
  });
</script>
<script>
  function initialMathJax() {
    MathJax.Hub.Queue(function () {
      var all = MathJax.Hub.getAllJax(),
        i;
      // console.log(all);
      for (i = 0; i < all.length; i += 1) {
        console.log(all[i].SourceElement().parentNode)
        all[i].SourceElement().parentNode.className += ' has-jax';
      }
    });
  }

  function reprocessMathJax() {
    if (typeof MathJax !== 'undefined') {
      MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
    }
  }
</script>



    
<link rel="stylesheet" href="//cdn.bootcss.com/gitalk/1.5.0/gitalk.min.css">

    
<script src="//cdn.bootcss.com/gitalk/1.5.0/gitalk.min.js"></script>



<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="/js/plugin.js"></script>
<script src="/js/obsidian.js"></script>
<script src="/js/jquery.truncate.js"></script>
<script src="/js/search.js"></script>


<script src="//cdn.bootcss.com/typed.js/2.0.10/typed.min.js"></script>


<script src="//cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js"></script>


<script src="//cdnjs.cloudflare.com/ajax/libs/social-share.js/1.0.16/js/social-share.min.js"></script>


<script src="https://cdn.bootcss.com/codemirror/5.48.4/codemirror.min.js"></script>

    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/javascript/javascript.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/css/css.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/xml/xml.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/htmlmixed/htmlmixed.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/clike/clike.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/php/php.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/shell/shell.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/python/python.min.js"></script>




    
<script src="/js/busuanzi.min.js"></script>

    <script>
        $(document).ready(function () {
            if ($('span[id^="busuanzi_"]').length) {
                initialBusuanzi();
            }
        });
    </script>



<link rel="stylesheet" href="//cdn.bootcss.com/photoswipe/4.1.3/photoswipe.min.css">
<link rel="stylesheet" href="//cdn.bootcss.com/photoswipe/4.1.3/default-skin/default-skin.min.css">


<script src="//cdn.bootcss.com/photoswipe/4.1.3/photoswipe.min.js"></script>
<script src="//cdn.bootcss.com/photoswipe/4.1.3/photoswipe-ui-default.min.js"></script>


<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>
    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">
        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>
        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">
            <div class="pswp__top-bar">
                <!--  Controls are self-explanatory. Order can be changed. -->
                <div class="pswp__counter"></div>
                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
                <button class="pswp__button pswp__button--share" title="Share"></button>
                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                      <div class="pswp__preloader__cut">
                        <div class="pswp__preloader__donut"></div>
                      </div>
                    </div>
                </div>
            </div>
            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div> 
            </div>
            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>
            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>
            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>
        </div>
    </div>
</div>



    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="//www.googletagmanager.com/gtag/js?id=UA-149874671-1"></script>
    <script>
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());

        gtag('config', 'UA-149874671-1');
    </script>





<script>
    function initialTyped () {
        var typedTextEl = $('.typed-text');
        if (typedTextEl && typedTextEl.length > 0) {
            var typed = new Typed('.typed-text', {
                strings: ["Think like an artist, develop like an artisan", "艺术家思维去思考问题，工匠创造精神去开发"],
                typeSpeed: 90,
                loop: true,
                loopCount: Infinity,
                backSpeed: 20,
            });
        }
    }

    if ($('.article-header') && $('.article-header').length) {
        $(document).ready(function () {
            initialTyped();
        });
    }
</script>




</html>
